/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ejb;

import com.entidades.Aparelho;
import com.entidades.dao.DaoBasico;
import com.entidades.enumerandos.StatusAparelhoEnum;


import com.util.WorkerEJBUtil;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.UserTransaction;

/**
 *
 * @author Ricardo
 */
@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class AparelhoBean implements AparelhoRemote, AparelhoLocal {

    @Resource
    private UserTransaction utx;
    @PersistenceContext
    private EntityManager em;


    public void gravar(Aparelho a) {
        a.setStatus(StatusAparelhoEnum.DESCONECTADO);
        a.setDataHoraUltimoEnvio(new Date());
        if (a.getId() != null) {
            DaoBasico.merge(a, em, utx);

        } else {
            DaoBasico.persist(a, em, utx);
        }

    }

    public List<Aparelho> findAll() {
        List<Aparelho> lista = new ArrayList<Aparelho>();

        Query query = em.createQuery("Select a from Aparelho a");
        lista = query.getResultList();

        /*
         * Atualiza Status Aparelho
         */
        if (lista != null && lista.size() > 0) {
            for (Aparelho aparelho : lista) {
                atualizaStatusAparelho(aparelho);
            }
        }
        return lista;
    }

    /**
     *  Verifica se o aparelho esta no mapa.
    Caso esteja coloca o Status como conectado
     * @param aparelho
     */
    private void atualizaStatusAparelho(Aparelho aparelho) {
        OperadorRemote operadorRemote = null;
        try {
            operadorRemote = WorkerEJBUtil.getOperadorBean(aparelho, em);
            aparelho.setStatus(StatusAparelhoEnum.DESCONECTADO);


            if (operadorRemote != null && operadorRemote.isPortaConectada(aparelho.getPorta())) {
                aparelho.setStatus(StatusAparelhoEnum.CONECTADO);
            }
        } catch (NamingException ex) {
            Logger.getLogger(AparelhoBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        DaoBasico.merge(aparelho, em, utx);
    }

    public Aparelho findById(Long id) {
        return em.find(Aparelho.class, id);

    }

    public void deletar(Aparelho a) {
        a = (Aparelho) DaoBasico.merge(a, em, utx);
        DaoBasico.remove(a, em, utx);

    }

    /**
     * Solicita a conexão com a porta lógica do aparelho
     * @param a
     * @return
     */
    public String setupAparelhoPasso1(Aparelho a) {

        String retorno = "";
        try {
            OperadorRemote OperadorRemote = WorkerEJBUtil.getOperadorBean(a, em);
            retorno = OperadorRemote.conectarAparelho(a.getPorta());

            a.setStatus(StatusAparelhoEnum.AGUARDANDO_START);
            DaoBasico.merge(a, em, utx);

        } catch (NamingException ex) {
            retorno = "Erro - falha de conexão"; //TODO aparelho indisponivél
            Logger.getLogger(AparelhoBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            retorno = "Erro - falha de conexão"; //TODO aparelho indisponivél
            Logger.getLogger(AparelhoBean.class.getName()).log(Level.SEVERE, null, ex);
        }

        return retorno;

    }

    /**
     * Envia mensagem propositalmente para liberar os envios
     * @param a
     * @return
     */
    public String setupAparelhoPasso2(Aparelho a) {
        String retorno = "";
        try {
            OperadorRemote OperadorRemote = WorkerEJBUtil.getOperadorBean(a, em);
            //retorno = OperadorRemote.enviar4Idem(a.getNumero(), "aparelho ligado: " + a.getIdentificador(), a.getPorta(), "MMS");
            a.setStatus(StatusAparelhoEnum.CONECTADO);
            DaoBasico.merge(a, em, utx);

        } catch (NamingException ex) {
            Logger.getLogger(AparelhoBean.class.getName()).log(Level.SEVERE, null, ex);
            retorno = "Erro - falha de conexão";
        } catch (Exception ex) {
            retorno = "Erro - falha de conexão"; //TODO aparelho indisponivél
            Logger.getLogger(AparelhoBean.class.getName()).log(Level.SEVERE, null, ex);
        }

        return retorno;
    }

    public String desconectar(Aparelho a) {


        String retorno = "";
        try {
            OperadorRemote OperadorRemote = WorkerEJBUtil.getOperadorBean(a, em);

            retorno = OperadorRemote.desconectarAparelho(a.getPorta(), a.getTipo().toString());

        } catch (NamingException ex) {
            Logger.getLogger(AparelhoBean.class.getName()).log(Level.SEVERE, null, ex);
            retorno = "Erro - falha de conexão";
        } catch (Exception ex) {
            retorno = "Erro - falha de conexão"; //TODO aparelho indisponivél
            Logger.getLogger(AparelhoBean.class.getName()).log(Level.SEVERE, null, ex);
        }

        a.setStatus(StatusAparelhoEnum.DESCONECTADO);
        a.setInfo(retorno);
        DaoBasico.merge(a, em, utx);

        return retorno;
    }

    public String conectarUSBModem(Aparelho aparelho) {
        String retorno = "";
        try {
            OperadorRemote operadorRemote = WorkerEJBUtil.getOperadorBean(aparelho, em);
            retorno = operadorRemote.conectarAparelhoUSBModem(aparelho.getPorta());



            aparelho.setStatus(StatusAparelhoEnum.CONECTADO);

        } catch (NamingException ex) {
            Logger.getLogger(AparelhoBean.class.getName()).log(Level.SEVERE, null, ex);
            retorno = "Erro ao conectar aparelho - Falha de conexão";
            aparelho.setStatus(StatusAparelhoEnum.DESCONECTADO);
        } catch (Exception ex) {
            aparelho.setStatus(StatusAparelhoEnum.DESCONECTADO);
            retorno = "Erro ao conectar aparelho - Falha de conexão"; //TODO aparelho indisponivél
            Logger.getLogger(AparelhoBean.class.getName()).log(Level.SEVERE, null, ex);
        }


        aparelho.setInfo(retorno);
        DaoBasico.merge(aparelho, em, utx);

        return retorno;


    }
}
